<?php
/**
 * FooModel.php
 * Model class to access to FooVision database functions
 *
 * $Id: FooModel.php 65 2007-09-22 01:02:43Z jonathan.hernandez $
 */

require_once "FooException.php";

class FooModel {

    private $db;

    private $imagesDir;

    private $imagesUrl;

    private $resizeMethod;

    private $salt;

    function __construct($conf = array())
    {
        require_once 'FooDB.php';
        $this->db = new FooDB($conf['db']);
        $this->db->connect();
        $this->imagesDir = $conf['images_dir'];
        $this->imagesUrl = $conf['images_url'];
        $this->resizeMethod = $conf['resize_method'];
        $this->salt = $conf['salt'];
    }

    private function getNodeId($username)
    {
        $sql = 'SELECT 
                   id
                FROM 
                    nodes 
                WHERE 
                    username = {username}';
        $id = $this->db->queryOne($sql, array('username' => $username));
        return (int)$id;
    }

    public function getNodeImages($username, $last_update, $with_friends) 
    {
        $params = array();
        $params['username'] = $username;
        $params['last_update'] = $last_update;
        
        if ($with_friends) {
            $params['id'] = $this->getNodeId($username);
            $sql = 'SELECT 
                        node, username, 
                        images.id AS img_id,
                        sender, imagename, images.createtime
                    FROM 
                        images 
                        INNER JOIN nodes ON node_id = nodes.id 
                    WHERE 
                        images.createtime > {last_update}
                        node_id IN 
                            (   SELECT friend_id 
                                FROM node_friends 
                                WHERE node_friends.node_id = {id}
                                UNION 
                                SELECT {id} FROM dual)';
        } else {
            $sql = 'SELECT 
                        node, username,
                        images.id AS img_id, 
                        sender, imagename, filename, images.createtime 
                    FROM 
                        nodes 
                        INNER JOIN images 
                        ON nodes.id = images.node_id
                    WHERE 
                        images.createtime > {last_update}
                        AND username = {username}';
        }

        if ($last_update == 0) {
            $sql .= ' ORDER BY images.createtime DESC LIMIT 1 ';
        }
        
        $result = $this->db->queryAll($sql, $params);
        if (count($result) > 0) {
            $json = '[';
            foreach ($result as $row) {
                $url = $this->imagesUrl . '/' . $row['username'] . '/' . $row['filename'];
                $urlSq = $this->imagesUrl . '/' . $row['username'] . '/square/' . $row['filename'];
                $urlTh = $this->imagesUrl . '/' . $row['username'] . '/thumb/' . $row['filename'];
                
                $aux   = explode(' ', $row['createtime']);
                $aux   = implode(',', array_merge(explode('-', $aux[0]), explode(':', $aux[1])));
                $createtime = 'new Date('.$aux.')';
                
                $json .= '{';
                $json .= 'node:"'.str_replace('"','\"', $row['node']).'",';
                $json .= 'username:"'.str_replace('"','\"', $row['node']).'",';
                $json .= 'url:"'.$url.'",';
                $json .= 'urlSq:"'.$urlSq.'",';
                $json .= 'urlTh:"'.$urlTh.'",';
                $json .= 'sender:"'.str_replace('"','\"', $row['sender']).'",';
                $json .= 'name:"'.str_replace('"','\"', $row['imagename']).'",';
                $json .= 'date:'.$createtime.',';
                $json .= 'createtime:"'.$row['createtime'].'"';
                $json .= '},';
            }
            if (strlen($json) > 1) {
                $json = substr($json, 0, -1);
            }
            $json .= ']';
            return $json;
        }
        return false;
    }

    public function newUser($username, $password, $email, $node, $location, $timezone)
    {
        throw new FooException('Method newUser implemented', FOOEXC_NOTIMPLEMENTED);
        $params = array();
        $params['username'] = $username; 
        $params['password'] = md5($this->salt, $password);
        $params['email']    = $email;
    }

    private function validUser($username, $password) 
    {
        $sql = 'SELECT 
                   id, username
                FROM 
                    nodes 
                WHERE 
                    username = {username}
                    AND password = {password}';
        $params = array();
        $params['username'] = $username;
        $params['password'] = md5($this->salt.$password);
        
        if (!$id = $this->db->queryOne($sql, $params)) {
            return false;
        }

        return $id;
    }

    public function receiveImage($username, $password, $sender, $imagename, $file)
    {
        // Validate user/password
        if (!$node_id = $this->validUser($username, $password)) {
            throw new Exception('Invalid username/password');
        }
        
        // Check file extension
        if (!eregi("\.png$|\.jpg$|\.jpeg$|\.gif|\.bmp$", $file['name'])) {
            throw new Exception('Invalid file extension');
        }
        
        $exploded = explode('.', $file['name']);
        $ext  = array_pop($exploded);
        $filename = basename($file['name'], '.'.$ext);
        
        if ($imagename == '') {
            $imagename = $filename;
        }

        $uploaddir = $this->imagesDir . '/' . $username . '/';

        if (!is_dir($uploaddir)) {
            if (!@mkdir($uploaddir, 0755)) {
                throw new Exception('Can\'t create upload directory');
            }
            if (!@mkdir($uploaddir.'/thumb', 0755)) {
                throw new Exception('Can\'t create upload directory');
            }
            if (!@mkdir($uploaddir.'/square', 0755)) {
                throw new Exception('Can\'t create upload directory');
            }
        }

        $found = true;
        $i = 0;
        $filename = preg_replace('|[^a-z0-9-]|i', '', $filename);
        while ($found) {
            $suffix = sprintf("%03d", $i);
            $newfile = $filename.'.'.$suffix .'.'.$ext;
            if (!file_exists($uploaddir.$newfile)) {
                $found = false;
            }
            $i++;
        }


        // Upload image
        if (!is_uploaded_file($file['tmp_name'])) {
            throw new Exception('Not an uploaded file');
        }

        if (!move_uploaded_file($file['tmp_name'], $uploaddir.$newfile)) {
            throw new Exception('Can\'t upload file');
        }

        // Create square
        require_once "FooImage.php";
        $im = new FooImage($this->resizeMethod);
        $im->resizeSquare($uploaddir.$newfile, $uploaddir.'/square/'.$newfile, 600);
        
        // Create thumb
        $im->resizeSquare($uploaddir.$newfile, $uploaddir.'/thumb/'.$newfile, 200);
        
        //Insert image in db
        $params = array();
        $params['node_id']    = $node_id;
        $params['sender']     = $sender;
        $params['imagename']  = $imagename;
        $params['filename']   = $newfile;
        $params['createtime'] = date('Y-m-d H:i:s');
    
        
        $sql = 'INSERT INTO images (node_id, sender, imagename, filename, createtime) 
                VALUES ({node_id}, {sender}, {imagename}, {filename}, {createtime})';
        if (!$result = $this->db->query($sql, $params)) {
            throw new Exception("Can't execute query");
        }

        $sql = "SELECT id 
                FROM images 
                WHERE 
                    node_id = {node_id} 
                    AND sender = {sender}
                    AND imagename = {imagename}
                    AND filename = {filename}
                    AND createtime = {createtime}";
                    
        if (!$id = $this->db->queryOne($sql, $params)) {
            throw new Exception("Query failed");
        }
                                                                                 
        return true;
    }

    public function getTheme($node) {
        $sql = "SELECT theme FROM nodes WHERE username = {node}";
        $params = array();
        $params['node'] = $node;
        if (!$theme = $this->db->queryOne($sql, $params)) {
            throw new Exception("Query failed");
        }
        
        if (!is_dir('themes/' . $theme)) {
            throw new Exception("Theme doesn't exists");
        }
        return $theme;
    }
}
